package com.cq.hd.order.utils;

import com.alibaba.fastjson.JSONObject;
import com.cq.hd.order.api.pft.PftDataResult;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import jodd.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.jackson.JsonComponentModule;
import org.springframework.data.geo.GeoModule;

import java.util.*;

@Slf4j
public class JSONUtil {

    private static ObjectMapper mapper = new ObjectMapper();

    static {
        mapper.setSerializationInclusion(JsonInclude.Include.ALWAYS);
        mapper.registerModule(new JavaTimeModule());
        mapper.registerModule(new GeoModule());
        mapper.registerModule(new JsonComponentModule());
    }

    public static String objectToJson(Object object) {
        if (object == null) {
            return null;
        }
        try {
            return mapper.writeValueAsString(object);
        } catch (Exception e) {
            log.warn("objectToJson get the ex===>", e);
        }
        return null;
    }

    public static <T> T jsonToObject(String json, Class<T> clazz) {
        return JSONObject.parseObject(json, clazz);
    }

    public static <T> T getPftDataResultRec(PftDataResult dataResult, Class<T> clazz) {
        JSONObject jsonObject = (JSONObject) dataResult.getData().getRec();
        return JSONObject.parseObject(jsonObject.toJSONString(), clazz);
    }

    public static <T> List<T> jsonToObjectList(String json, Class<T> clazz) {
        if (StringUtil.isBlank(json)) {
            return new ArrayList<>();
        }
        JavaType javaType = getCollectionType(List.class, clazz);
        try {
            return mapper.readValue(json, javaType);
        } catch (Exception e) {
            log.warn("jsonToObjectList get the ex===>", e);
        }
        return new ArrayList<>();
    }


    public static <T> LinkedHashSet<T> jsonToObjectSet(String json, Class<T> clazz) {
        if (StringUtil.isBlank(json)) {
            return new LinkedHashSet<>();
        }
        JavaType javaType = getCollectionType(LinkedHashSet.class, clazz);
        try {
            return mapper.readValue(json, javaType);
        } catch (Exception e) {
            log.warn("jsonToObjectSet get the ex===>", e);
        }
        return new LinkedHashSet<>();
    }

    public static <K, V> Map<K, V> jsonToMap(String json, Class<K> keyClazz, Class<V> valueClass) {
        if (StringUtil.isBlank(json)) {
            return new HashMap<>();
        }
        JavaType javaType = getMapType(keyClazz, valueClass);
        try {
            return mapper.readValue(json, javaType);
        } catch (Exception e) {
            log.warn("jsonToMap get the ex===>", e);
        }
        return new HashMap<>();
    }

    private static JavaType getCollectionType(Class<? extends Collection> collectionClass, Class<?>... elementClasses) {
        return mapper.getTypeFactory().constructParametricType(collectionClass, elementClasses);
    }

    private static <K, V> JavaType getMapType(Class<K> kClass, Class<V> vClass) {
        return mapper.getTypeFactory().constructParametricType(Map.class, kClass, vClass);
    }


}
